package us.icitap.cm.ui.policecase;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import us.icitap.cm.CaseManagementUI;
import us.icitap.cm.business.entities.AppEntity;
import us.icitap.cm.business.entities.Case;
import us.icitap.cm.business.entities.EntityEntityAssociation;
import us.icitap.cm.business.entities.EntityTypeEnum;
import us.icitap.cm.business.entities.Report;
import us.icitap.cm.business.entities.ReportTypeEnum;
import us.icitap.cm.interfaces.ConfirmDialogAction;
import us.icitap.cm.listeners.AppEntityListener;
import us.icitap.cm.listeners.EntityEntityAssociationListener;
import us.icitap.cm.listeners.ReportListener;
import us.icitap.cm.ui.custom.CustButton;
import us.icitap.cm.ui.custom.CustConfirmDialog;
import us.icitap.cm.ui.shared.AppEntityLayout;
import us.icitap.cm.ui.shared.GeneralVars;
import us.icitap.cm.utils.HandleNotification;
import us.icitap.utils.Result;

import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.event.Action;
import com.vaadin.event.Action.Handler;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.VerticalLayout;

public class EventReportLayout extends VerticalLayout implements AppEntityListener,EntityEntityAssociationListener, ReportListener{

	
	EventReportTree erTree = new EventReportTree();
	
	private final CustButton cb = new CustButton("Ruaj");
	
	final EventReportDataLayout erDataLayout = new EventReportDataLayout();
	final PersonDataLayout personDataLayout = new PersonDataLayout();
	final PlaceDataLayout placeDataLayout = new PlaceDataLayout();
	final VehicleDataLayout vehicleDataLayout = new VehicleDataLayout();
	final ItemDataLayout itemDataLayout = new ItemDataLayout();
	final WeaponDataLayout weaponDataLayout = new WeaponDataLayout();
	final DrugDataLayout drugDataLayout = new DrugDataLayout();
	final OrganizationDataLayout organizationDataLayout = new OrganizationDataLayout();
	final OfficerDataLayout officerDataLayout = new OfficerDataLayout();
	final EntityEntityAssocDataLayout assocDataLayout = new EntityEntityAssocDataLayout();
	final DocumentDataLayout docDataLayout = new DocumentDataLayout();
	final ControlDataLayout controlDataLayout = new ControlDataLayout();
	
	
	final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
	
	private Case pCase;


	
	Map<EntityTypeEnum , AppEntityLayout> map = new HashMap<EntityTypeEnum, AppEntityLayout>();
	
	
	public EventReportLayout() {
	
		this.addComponent(splitPanel);
		
		VerticalLayout vl = new VerticalLayout();
		vl.addComponent(erTree);
		
		cb.setSizeFull();
		vl.addComponent(cb);
		cb.addClickListener(new ClickListener() {
			
			@Override
			public void buttonClick(ClickEvent event) {

				CustConfirmDialog.show(getConfirmDialogAction(), getUI(), "Jeni i sigurte qe doni te ruani raportin e ngjarjes?");
				
			}
		});
		
		
		splitPanel.setFirstComponent(vl);
		
		splitPanel.setHeight("700px");
		splitPanel.setMinSplitPosition(200, Unit.PIXELS);
		splitPanel.setMaxSplitPosition(200, Unit.PIXELS);
		
		map.put(EntityTypeEnum.PLACE, this.placeDataLayout);
		map.put(EntityTypeEnum.PERSON, this.personDataLayout);
		map.put(EntityTypeEnum.VEHICLE, this.vehicleDataLayout);
		map.put(EntityTypeEnum.DRUG, this.drugDataLayout);
		map.put(EntityTypeEnum.WEAPON, this.weaponDataLayout);
		map.put(EntityTypeEnum.ITEM, this.itemDataLayout);
		map.put(EntityTypeEnum.ORGANIZATION, this.organizationDataLayout);
		map.put(EntityTypeEnum.OFFICER, this.officerDataLayout);
		map.put(EntityTypeEnum.DOCUMENT, this.docDataLayout);
		map.put(EntityTypeEnum.CONTROL, this.controlDataLayout);
		
		for (Iterator iterator = map.values().iterator(); iterator.hasNext();) {
			AppEntityLayout appEntityLayout = (AppEntityLayout) iterator.next();
			appEntityLayout.addAppEntityListener(this);
		}
		erDataLayout.addReportListener(this);
		
		
		
		
		erTree.addValueChangeListener(new ValueChangeListener() {
			
			@Override
			public void valueChange(ValueChangeEvent event) {
				if(event.getProperty() != null){
					if("ASSOCIATIONS".equals(event.getProperty().getValue())){
						if(pCase.getLastReport() == null){
							HandleNotification.showWarningOnScreen("Ne fillim duhet te ruani te dhenat kryesore e raportit suplementar");
							return;
						}
						EventReportLayout.this.splitPanel.setSecondComponent(assocDataLayout);
					}
					else if(ReportTypeEnum.ER.equals(event.getProperty().getValue())){
						EventReportLayout.this.splitPanel.setSecondComponent(erDataLayout);
					}
					else{
						if (event.getProperty().getValue() instanceof AppEntity){
							AppEntity appEntity = (AppEntity) event.getProperty().getValue();
							loadAppEntity(appEntity);	
						}
						
					}
					
				}
				
			}
		});
		
		
		erTree.addActionHandler(new Handler() {
			
			@Override
			public void handleAction(Action action, Object sender, Object target) {

				if(action == GeneralVars.ADD){
					if(pCase.getLastReport() == null){
						HandleNotification.showWarningOnScreen("Ne fillim duhet te ruani te dhenat kryesore te raportit te ngjarjes");
						return;
					}
					System.out.println(target.toString());
					EventReportLayout.this.addAppEntity(EntityTypeEnum.valueOf(target.toString()));	
					erTree.select(target);
				}
				else if (action == GeneralVars.REMOVE){
					AppEntity appEntity = (AppEntity) target;
					
					CustConfirmDialog.show(
							EventReportLayout.this.getConfirmDialogActionRemoveAppEntity(appEntity), 
							CaseManagementUI.getCurrent(), "Jeni i sigurte qe doni te vazhdoni ta hiqni kete element? <br\\> Elementi nuk mund te rikthehet me por duhet te shtohet nga fillimi.");
				}
				
			}
			
			@Override
			public Action[] getActions(Object target, Object sender) {
				 if(target == null) return null;
				 if(target == EntityTypeEnum.PLACE
						 || target == EntityTypeEnum.PERSON
						 || target == EntityTypeEnum.VEHICLE
						 || target == EntityTypeEnum.WEAPON
						 || target == EntityTypeEnum.DRUG
						 || target == EntityTypeEnum.ORGANIZATION
						 || target == EntityTypeEnum.ITEM
						 || target == EntityTypeEnum.OFFICER
						 || target == EntityTypeEnum.DOCUMENT
						 || target == EntityTypeEnum.CONTROL)
	               return new Action[]{GeneralVars.ADD};
				 if(target instanceof AppEntity){
					 return new Action[]{GeneralVars.REMOVE};
				 }
				 return null;
			}
		});
		
		loadNewCase();
	}


	private void loadNewCase(){
		this.pCase = new Case();
		Report report = new Report(CaseManagementUI.getUser().getUsername());
		report.setReportOfficer(CaseManagementUI.getUser().getOfficer());
		report.setOrgStructure(CaseManagementUI.getUser().getOrgStructure());
		report.setReportType(ReportTypeEnum.ER);
	
//		this.assocDataLayout.loadCase(pCase);
		erDataLayout.addReport(report);
		controlDataLayout.setReport(report);
		assocDataLayout.setReport(report);
		assocDataLayout.addEntityEntityAssociationListener(this);
		EventReportLayout.this.splitPanel.setSecondComponent(erDataLayout);
		
		cb.setEnabled(false);
	}
	
	private void loadAppEntity(AppEntity appEntity){
		AppEntityLayout appEntityLayout = map.get(appEntity.getEntityType());
		
		appEntityLayout.loadAppEntity(appEntity, appEntity.isNewRecord());
		

		EventReportLayout.this.splitPanel.setSecondComponent(appEntityLayout);
	}
	
	private void addAppEntity(EntityTypeEnum entityTypeEnum){
		AppEntityLayout appEntityLayout = map.get(entityTypeEnum);

		appEntityLayout.addAppEntity();

		EventReportLayout.this.splitPanel.setSecondComponent(appEntityLayout);
	}
	
	private void addAppEntityToTree(AppEntity appEntity){
		this.erTree.addItem(appEntity);
		this.erTree.setParent(appEntity,appEntity.getEntityType());

		this.erTree.setItemCaption(appEntity.getEntityType(), appEntity.getEntityType().getCaption() + "(" + erTree.getChildren(appEntity.getEntityType()).size() + ")");

	}

	private ConfirmDialogAction getConfirmDialogAction(){
		ConfirmDialogAction confirm = new ConfirmDialogAction(){

			@Override
			public void actYes() {
				
				Result<Case> result =CaseManagementUI.appStatelessBean.getPersistenceBean().saveReport(pCase);
				if(result.isSucceeded()){
					HandleNotification.showInfoOnTray("Ceshtja u ruajt me sukses");
//					loadCase(result.getObject());
				}
					
					
				else
					HandleNotification.showErrorOnScreen(result.getMessage());
				
			}

			@Override
			public void actNO() {
				// TODO Auto-generated method stub
				
			}
			
		};
		return confirm;
	}

	private ConfirmDialogAction getConfirmDialogActionRemoveAppEntity(final AppEntity appEntity){
		ConfirmDialogAction confirm = new ConfirmDialogAction(){

			@Override
			public void actYes() {
				removeAppEntityFromReport(appEntity);
				HandleNotification.showInfoOnTray("Elementi :" + appEntity.getEntityType().getCaption() + " : " + appEntity.toString() + " u hoq me sukses."  );
			}

			@Override
			public void actNO() {
				
				
			}
			
		};
		
		return confirm;
	}
	@Override
	public void storeInMemory(Report report) {
		if(pCase.getReportList() != null) return;
		pCase.addReport(report);
		report.setPoliceCase(pCase);
		pCase.setLastReport(report);
		if(pCase.getLastReport().getEventReport().getUniqueNumber().isUnGenerated())
			erTree.setItemCaption(ReportTypeEnum.ER, pCase.getLastReport().getEventReport().getUniqueNumber().getUniqueNumber() + ", " + pCase.getLastReport().getPrimaryPoliceCode().getTag());
		else
			erTree.setItemCaption(ReportTypeEnum.ER, pCase.getLastReport().getPrimaryPoliceCode().getTag());
		
		cb.setEnabled(true);
		
	}


	@Override
	public void addAppEntityToReport(AppEntity appEntity) {
		if(appEntity != null){
			if(appEntity.getEntityType().equals(EntityTypeEnum.CONTROL)){
				appEntity.getControl().setReport(pCase.getLastReport());
				pCase.getLastReport().addControl(appEntity.getControl());
			}
			else{
				pCase.getLastReport().addAppEntity(appEntity);
			}
			
			this.addAppEntityToTree(appEntity);
		}
		
		
		
	}


	@Override
	public void removeAppEntityFromReport(AppEntity appEntity) {
		if(pCase.getLastReport().getEntityEntityAssocList() != null){
			for (Iterator<EntityEntityAssociation> iterator = pCase.getLastReport().getEntityEntityAssocList().iterator(); iterator.hasNext();) {
				EntityEntityAssociation eea = iterator.next();
				if(eea.getEntityOne().equals(appEntity)) iterator.remove();
				else if(eea.getEntityTwo().equals(appEntity)) iterator.remove();
			}
		}

		pCase.getLastReport().removeAppEntity(appEntity);
		
		erTree.removeItem(appEntity);
		if(erTree.getChildren(appEntity.getEntityType()) == null)
			erTree.setItemCaption(appEntity.getEntityType(), appEntity.getEntityType().getCaption());
		else
			erTree.setItemCaption(appEntity.getEntityType(), appEntity.getEntityType().getCaption() + "(" + erTree.getChildren(appEntity.getEntityType()).size() + ")");
		
	}


	@Override
	public void updateAppEntityIntoReport(AppEntity oldValue, AppEntity newValue) {
		
		pCase.getLastReport().removeAppEntity(oldValue);
		
		if(pCase.getLastReport().getEntityEntityAssocList() != null){
			for (EntityEntityAssociation eea : pCase.getLastReport().getEntityEntityAssocList()) {
				if(eea.getEntityOne().equals(oldValue)) eea.setEntityOne(newValue);
				if(eea.getEntityTwo().equals(oldValue)) eea.setEntityTwo(newValue);
			}
		}

		erTree.removeItem(oldValue);
		pCase.getLastReport().addAppEntity(newValue);

		this.addAppEntityToTree(newValue);
		erTree.markAsDirty();
	}

	@Override
	public void refresh(AppEntity appEntity) {	

		erTree.markAsDirty();
		
	}


	@Override
	public void addEntityEntityAssociation(EntityEntityAssociation eea) {
		if (pCase.getLastReport().getEntityEntityAssocList() != null ){
			for (EntityEntityAssociation e : pCase.getLastReport().getEntityEntityAssocList()) {
				if(e.myEquals(eea)) return;
			}
			
		}
		eea.getEntityOne().addEntityAssocAsOne(eea);
		eea.getEntityTwo().addEntityAssocAsTwo(eea);
		eea.setReport(pCase.getLastReport());
		pCase.getLastReport().addEntityEntityAssociation(eea);
		
	}

	@Override
	public void removeEntityEntityAssociation(EntityEntityAssociation eea) {
		if (pCase.getLastReport().getEntityEntityAssocList() != null && !pCase.getLastReport().getEntityEntityAssocList().isEmpty()){
			for (EntityEntityAssociation e : pCase.getLastReport().getEntityEntityAssocList()) {
				if(e.myEquals(eea)) {
					pCase.getLastReport().getEntityEntityAssocList().remove(e);
					return;
				}
			}
		}
		
	}
	
}
